package netty.rpc.framework.core.netty.transport.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;
import netty.rpc.framework.core.netty.transport.codec.Byte2RPCMessageDecoder;
import netty.rpc.framework.core.netty.transport.codec.RPCMessage2ByteEncoder;

import java.util.concurrent.TimeUnit;

/**
 * Netty服务端Server启动相关类
 */
@Slf4j
public class NettyServer {

    private final int serverPort;

    ServerBootstrap serverBootstrap = new ServerBootstrap();
    /**
     * 初始化Netty服务端配置
     *
     * @param serverPort 服务端监听端口
     */

    public NettyServer(int serverPort) {
        this.serverPort = serverPort;
    }

    public void runServer() {
        //创建反应器线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workGroup = new NioEventLoopGroup(2);

        //设置反应器线程组
        serverBootstrap.group(bossGroup, workGroup);
        //设置nio通道类型
        serverBootstrap.channel(NioServerSocketChannel.class);
        //设置监听端口
        serverBootstrap.localAddress(serverPort);
        //设置通道参数
        serverBootstrap.option(ChannelOption.SO_KEEPALIVE, true);
        //装配子通道流水线
        serverBootstrap.childHandler(
                new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        //添加handler处理器
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        //添加心跳处理器
                        pipeline.addLast(new IdleStateHandler(10,0,0, TimeUnit.SECONDS));

                        pipeline.addLast(new Byte2RPCMessageDecoder());
                        pipeline.addLast(new RPCMessage2ByteEncoder());
                        pipeline.addLast(new ServiceHandler());

                    }
                }
        );
        //开始绑定服务器
        try {
            ChannelFuture sync = serverBootstrap.bind().sync();
            log.info("服务器启动成功，监听端口:{}", sync.channel().localAddress());
            //等待通道关闭的异步任务结束
            ChannelFuture channelFuture = sync.channel().closeFuture();
            channelFuture.sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
            log.error("服务器启动失败");
        } finally {
            //释放资源
            workGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }


    }

}


